package com.leetcode.midium;

/**
 * @author zfl
 * @Classname LongestPalindrome
 * @Description
 * @Date 2020/10/9 16:37
 */
public class LongestPalindrome {

    /**
     * @param s
     * @return
     * 动态规划
     */
    public static String longestPalindrome1(String s) {
        String result = "";
        boolean table[][] = new boolean[s.length()][s.length()];
        // length === 1;
        for (int i = 0; i < table.length; i++) {
            table[i][i] = true;
            result = s.substring(i, i + 1);
        }

        // length === 2
        for (int i = 0; i < table.length - 1; i++) {
            if(s.charAt(i) == s.charAt(i + 1)) {
                table[i][i + 1] = true;
                result = s.substring(i, i + 2);
            }else {
                table[i][i + 1] = false;
            }
        }

        // length > 2
        for (int len = 3; len <= table.length; len++) {
            for (int i = 0; i + len <= table.length ; i++) {
                char front = s.charAt(i);
                char end = s.charAt(i + len - 1);
                if(front == end) {
                    table[i][i + len - 1] = table[i + 1][i + len - 2];
                }else {
                    table[i][i + len - 1] = false;
                }
                if(table[i][i + len - 1]) {
                    result = s.substring(i, i + len);
                }
            }
        }
        return result;
    }

    /**
     * @param s
     * @return
     * 动态规划
     */
    public static String longestPalindrome2(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        String ans = "";
        for (int len = 0; len < n; ++len) {
            for (int i = 0; i + len < n; ++i) {
                int j = i + len;
                if (len == 0) {
                    dp[i][j] = true;
                } else if (len == 1) {
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                } else {
                    dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
                }
                if (dp[i][j] && len + 1 > ans.length()) {
                    ans = s.substring(i, i + len + 1);
                }
            }
        }
        return ans;
    }

    /**
     * @param s
     * @return
     * 中心扩散法
     * 执行用时：34 ms, 在所有 Java 提交中击败了77.13%的用户
     * 内存消耗：39 MB, 在所有 Java 提交中击败了60.80%的用户
     */
    public static String longestPalindrome3(String s) {
        if(s == null || s.length() < 1) {
            return "";
        }
        int start = 0, end = 0;
        for(int i = 0;i < s.length(); i++) {
            int len1 = expandAroundCenter(s,i,i);
            int len2 = expandAroundCenter(s,i,i + 1);
            int len = Math.max(len1,len2);
            if(len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        return s.substring(start, end + 1);
    }

    public static int expandAroundCenter(String s, int left, int right) {
        while(left >= 0 && right < s.length() && (s.charAt(left) == s.charAt(right))) {
            --left;
            ++right;
        }
        return right - left - 1;
    }
}
